package com.ihr360.shared.sequence.expression;

import com.ihr360.expr.ExprError;
import com.ihr360.expr.ExprException;
import com.ihr360.expr.context.IEvaluationContext;
import com.ihr360.expr.core.Expr;
import com.ihr360.expr.core.ExprFunction;
import com.ihr360.expr.core.ExprVariable;
import com.ihr360.expr.engine.VariableFetcher;
import com.ihr360.expr.function.FunctionManager;
import com.ihr360.expr.parser.ExprLexer;
import com.ihr360.expr.parser.ExprParser;
import com.ihr360.shared.sequence.expression.function.SerialFunctionProvider;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SerialNumberEvaluation implements IEvaluationContext{
    public static final String MAXID = "MAXID";

    public static final String yyyy = "YYYY";
    public static final String yyyyMM = "YYYYMM";
    public static final String yyyyMMdd = "YYYYMMDD";
    public static final String yyyyMMddHH = "YYYYMMDDHH";
    public static final String yyyyMMddHHmm = "YYYYMMDDHHMM";
    public static final String yyyyMMddHHmmss = "YYYYMMDDHHMMSS";
    public static final String yyyyMMddHHmmssSS = "YYYYMMDDHHMMSSSS";

    public static final List<String> dateTypeList = new ArrayList<>();

    public static final List<String> categoryIdTypeList = new ArrayList<>();

    static {
        //时间格式
        dateTypeList.add(yyyy);
        dateTypeList.add(yyyyMM);
        dateTypeList.add(yyyyMMdd);
        dateTypeList.add(yyyyMMddHH);
        dateTypeList.add(yyyyMMddHHmm);
        dateTypeList.add(yyyyMMddHHmmss);
        dateTypeList.add(yyyyMMddHHmmssSS);
        //分组清零格式
        categoryIdTypeList.add(yyyy);
        categoryIdTypeList.add(yyyyMM);
        categoryIdTypeList.add(yyyyMMdd);
    }


    private FunctionManager functions = new FunctionManager();
    private Map<String, Expr> variables = new HashMap<>();
    VariableFetcher variableFetcher = null;
    public Expr parse(String expr) throws IOException, ExprException {
        ExprParser ep = new ExprParser();
        ep.parse(new ExprLexer(expr));
        return ep.get();
    }


    public SerialNumberEvaluation(VariableFetcher variableFetcher) {
        functions.add(new SerialFunctionProvider());
        this.variableFetcher = variableFetcher;
    }

    public SerialNumberEvaluation() {
        functions.add(new SerialFunctionProvider());
    }


    public void addVariable(String name, Expr value) {
        variables.put(name, value);
    }

    @Override
    public Expr evaluateFunction(ExprFunction function) throws ExprException {
        return functions.evaluate(this, function);
    }

    @Override
    public Expr evaluateVariable(ExprVariable variable) throws ExprException {
        String name = variable.getName().toUpperCase();
        if (variables.containsKey(name)) {
            return variables.get(name);
        }
        Expr e = variables.get(name);
        if (e == null){
            if (this.variableFetcher!=null){
                e = this.variableFetcher.variable( variable.getName());
            }
            if (e!=null){
                return e;
            }
            return ExprError.NAME;
        }
        return e;
    }

}